home *** CD-ROM | disk | FTP | other *** search
- /*
- * SFtoSpr - Star Fighter 3000 graphics converter
- * Main application skeleton
- * Copyright (C) 2000 Chris Bazley
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public Licence as published by
- * the Free Software Foundation; either version 2 of the Licence, or
- * (at your option) any later version.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
- * GNU General Public Licence for more details.
- *
- * You should have received a copy of the GNU General Public Licence
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- */
-
- /* ANSI library files */
- #include <stdlib.h>
- #include <string.h>
- #include <stdbool.h>
- #include <signal.h>
- #include <ctype.h>
- #include <stdio.h>
-
- /* RISC OS library files */
- #include "kernel.h"
- #include "toolbox.h"
- #include "event.h"
- #include "flex.h"
- #include "wimp.h"
- #include "wimplib.h"
-
- /* My library files */
- #include "err.h"
- #include "msgtrans.h"
- #include "hourglass.h"
- #include "Macros.h"
- #include "Loader.h"
- #include "SFformats.h"
- #include "ViewsMenu.h"
- #include "RoundRobin.h"
- #include "InputFocus.h"
- #include "nobudge.h"
-
- /* Local headers */
- #include "SFIconbar.h"
- #include "SFgfxconv.h"
- #include "Scan.h"
- #include "Utils.h"
- #include "Main.h"
- #include "SFMenu.h"
- #include "PreQuit.h"
-
- #define WimpVersion 310
-
- /* This is the MINIMUM amount of work we do per null poll (Since our
- RoundRobinHandler isn't very well written, the maximum time slice is
- this PLUS the time to convert, load or save the largest file). We
- null poll as often as possible, like a program running under the
- TaskWindow module. The event mask is used (rather than
- Wimp_PollIdle) to avoid receiving unnecessarily null events. */
- #define NULL_TIME_SLICE 10
-
- _kernel_oserror shared_err_block = {255, ""};
- bool verify_spriteareas;
- char taskname[32];
- int wimp_version;
- bool multi_saveboxes = false;
- bool quit_parse_cl = false;
- bool output_new_format = false;
- int timeslice = NULL_TIME_SLICE;
- ObjectId last_savebox = NULL_ObjectId;
-
- static WimpPollBlock poll_block;
- static IdBlock id_block;
-
- /* ----------------------------------------------------------------------- */
- /* Function prototypes */
-
- static WimpMessageHandler WimpPreQuit_handler, WimpQuit_handler;
- static ToolboxEventHandler autocreate_handler, error_handler;
- static void initialise(void);
- static void process_arguments(int argc, char *argv[]);
- static void load_cl_files(int argc, char *argv[]);
- static LoaderFinishedHandler display_tiles, display_planets;
- static void simple_exit(_kernel_oserror *e);
-
- /* ----------------------------------------------------------------------- */
- /* Public functions */
-
- int main(int argc, char *argv[])
- {
- process_arguments(argc, argv);
- initialise();
- load_cl_files(argc, argv);
- if(quit_parse_cl)
- WimpQuit_handler(NULL, NULL);
-
- /*
- * poll loop
- */
-
- while (TRUE) {
- int event_code;
- event_poll (&event_code, &poll_block, NULL);
- }
- }
-
- /* ----------------------------------------------------------------------- */
- /* Private functions */
-
- static int WimpPreQuit_handler(WimpMessage *message, void *handle)
- {
- int th;
- if(message->hdr.size < 20 || message->data.words[0] == 0)
- th = message->hdr.sender; /* shutdown in progress */
- else
- th = 0; /* just our task */
-
- /* If function returns false then unsaved data */
- if(!TRY_QUIT(th)) {
- /* Object by acknowledging message */
- message->hdr.your_ref = message->hdr.my_ref;
- RE(wimp_send_message(Wimp_EUserMessageAcknowledge, message, message->hdr.sender, NULL, NULL));
- }
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int WimpQuit_handler(WimpMessage *message,void *handle)
- {
- exit(EXIT_SUCCESS);
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int autocreate_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- /* Catch auto-created objects and initialise handlers etc. */
- ToolboxObjectAutoCreatedEvent *toace = (ToolboxObjectAutoCreatedEvent *)event;
-
- if(strcmp(toace->template_name, "Menu") == 0) {
- Menu_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- if (strcmp(toace->template_name, "PreQuit") == 0) {
- PreQuit_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- if (strcmp(toace->template_name, "Iconbar") == 0) {
- Iconbar_initialise(id_block->self_id);
- return 1; /* claim event */
- }
- return 0; /* pass event on */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static int error_handler(int event_code, ToolboxEvent *event, IdBlock *id_block, void *handle)
- {
- ToolboxErrorEvent *totee = (ToolboxErrorEvent *)event;
-
- if(totee->errnum == 0x80b633 || totee->errnum == 0x131c3) /* "To save drag...", locked file */
- err_report(totee->errnum, totee->errmess);
- else
- err_complain(totee->errnum, totee->errmess);
-
- return 1; /* claim event */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void initialise(void)
- {
- int toolbox_events = 0,
- wimp_messages = 0;
-
- hourglass_on();
-
- /*
- * Prevent termination on SIGINT (we use the escape key ourselves)
- */
- signal(SIGINT, SIG_IGN);
-
- /*
- * register ourselves with the Toolbox.
- */
-
- {
- _kernel_oserror *e = toolbox_initialise (0, WimpVersion, &wimp_messages, &toolbox_events, "<SFtoSprRes$Dir>",msgs_get_descriptor(), &id_block, &wimp_version, 0, 0);
- if(e != NULL)
- simple_exit(e);
- }
-
- strncpy(taskname, msgs_lookup("_TaskName"), sizeof(taskname)-1);
- err_set_taskname(taskname, (wimp_version >= 321));
-
- /*
- * initialise the flex library
- */
-
- flex_init(taskname, (int *)msgs_get_descriptor(), 0); /* (use Wimpslot and own messages file) */
- flex_set_budge(1); /* allow budging of flex when heap extends */
-
- /*
- * initialise the event library.
- */
-
- event_initialise (&id_block);
- event_set_mask (Wimp_Poll_NullMask |
- Wimp_Poll_PointerLeavingWindowMask |
- Wimp_Poll_PointerEnteringWindowMask |
- Wimp_Poll_KeyPressedMask | /* Dealt with by Toolbox */
- Wimp_Poll_LoseCaretMask |
- Wimp_Poll_GainCaretMask);
-
- EF(event_register_toolbox_handler(-1, Toolbox_ObjectAutoCreated, autocreate_handler, 0));
- EF(event_register_toolbox_handler(-1, Toolbox_Error, error_handler, 0));
- EF(event_register_message_handler(Wimp_MPreQuit, WimpPreQuit_handler, 0));
- EF(event_register_message_handler(Wimp_MQuit, WimpQuit_handler, 0));
-
- EF(InputFocus_initialise());
- EF(RoundRobin_initialise(timeslice));
-
- /*
- * Initialise other components.
- */
-
- EF(loader_initialise(0));
-
- /* Capture Filer double-clicks of MapTiles/Planets and act separately from drags to app icon */
- EF(loader_register_listener(LISTENER_CLAIM, FILETYPE_MAPTILES, NULL, NULL, load_compressed, display_tiles, NULL));
- EF(loader_register_listener(LISTENER_CLAIM, FILETYPE_PLANETS, NULL, NULL, load_compressed, display_planets, NULL));
-
- /* Check for SpriteExtend 0.99 (can we verify SAs?) */
- EF(_kernel_setenv("SFtoSpr$Verify","1"));
- if(_kernel_oscli("RMEnsure SpriteExtend 0.99 Set SFtoSpr$Verify 0") == _kernel_ERROR)
- err_check_fatal_rep(_kernel_last_oserror());
- {
- char readvar_buffer[16];
- EF(_kernel_getenv("SFtoSpr$Verify", readvar_buffer, sizeof(readvar_buffer)));
- verify_spriteareas = (strcmp(readvar_buffer, "1") == 0);
- EF(_kernel_setenv("SFtoSpr$Verify",NULL));
- }
-
- EF(ViewsMenu_create());
-
- hourglass_off();
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void load_cl_files(int argc, char *argv[])
- {
- /*
- * Load any files specified as command-line arguments
- */
-
- for(int i = 1; i < argc; i++) {
- /* anything without a '-' in front is interpreted as a file to load */
- if (*argv[i] != '-' && (i < 2 || !ViewsMenu_strcmp_nc(argv[i-1], "-timeslice"))) {
-
- /* get filetype (can't use _kernel_osfile as it doesn't return R6) */
- _kernel_swi_regs regs;
- regs.r[0] = 23;
- regs.r[1] = (int)argv[i];
- if(!E(_kernel_swi(OS_File, ®s, ®s))) {
- _kernel_oserror *err;
- void *cl_buffer;
-
- switch(regs.r[6]) {
- case FILETYPE_MAPTILES:
- err = load_compressed(argv[i], (flex_ptr)&cl_buffer);
- if(err == NULL)
- display_tiles(argv[i], 1, (flex_ptr)&cl_buffer, FILETYPE_MAPTILES, NULL);
- else {
- err_complain(0, msgs_lookup_sub1("LoadFail", err->errmess));
- flex_free((flex_ptr)&cl_buffer);
- }
- break;
-
- case FILETYPE_PLANETS:
- err = load_compressed(argv[i], (flex_ptr)&cl_buffer);
- if(err == NULL)
- display_planets(argv[i], 1, (flex_ptr)&cl_buffer, FILETYPE_PLANETS, NULL);
- else {
- err_complain(0, msgs_lookup_sub1("LoadFail", err->errmess));
- flex_free((flex_ptr)&cl_buffer);
- }
- break;
- }
- } /* got filetype OK */
- } /* parameter is filename */
- } /* next parameter */
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void simple_exit(_kernel_oserror *e)
- {
- /* Limited amount we can do with no messages file... */
- wimp_report_error(e, Wimp_ReportError_Cancel, "SFtoSpr");
- exit(EXIT_FAILURE);
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void process_arguments(int argc, char *argv[])
- {
- /*
- * Look at command-line parameters
- */
-
- for(int i = 1; i < argc; i++) {
- if(ViewsMenu_strcmp_nc(argv[i], "-quit"))
- quit_parse_cl = true;
- else {
- if(ViewsMenu_strcmp_nc(argv[i], "-multi"))
- multi_saveboxes = true;
- else {
- if(ViewsMenu_strcmp_nc(argv[i], "-newformat"))
- output_new_format = true;
- else {
- if(ViewsMenu_strcmp_nc(argv[i], "-timeslice") && i+1 < argc) {
- for(int c = 0; c < strlen(argv[i+1]); c++) {
- if(!isdigit(argv[i+1][c])) {
- strcpy(shared_err_block.errmess, "Bad command line parameters");
- simple_exit(&shared_err_block);
- }
- }
- sscanf(argv[i+1], "%d", ×lice);
- } else {
- if(*argv[i] == '-') {
- /* Catches unknown options, but not time values or file paths */
- strcpy(shared_err_block.errmess, "Bad command line parameters");
- simple_exit(&shared_err_block);
- }
- }
- }
- }
- }
- }
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void display_tiles(char *file_path, bool data_saved, flex_ptr buffer, int filetype, void *handle)
- {
- /* Deal with Filer double-clicks on MapTiles files */
-
- /* convert to sprites */
- spriteareaheader *sprite_area;
- if(tiles_to_sprites((SF_MapTilesSetHdr **)buffer, &sprite_area)) {
-
- /* save spritefile to !Scrap */
- nobudge_register(256);
- _kernel_oserror *err = _swix(OS_SpriteOp, _INR(0,2), SPRITEOP_SAVE_AREA+SPRITEOP_USERAREA_SPRNAME, sprite_area, "<Wimp$Scrap>");
- nobudge_deregister();
- if(err != NULL)
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- else {
- /* open spritefile (in Paint?) */
- if(_kernel_oscli("Filer_Run <Wimp$Scrap>") == _kernel_ERROR)
- err_check_rep(_kernel_last_oserror());
- }
- flex_free((flex_ptr)&sprite_area);
- }
- flex_free(buffer);
- }
-
- /* ----------------------------------------------------------------------- */
-
- static void display_planets(char *file_path, bool data_saved, flex_ptr buffer, int filetype, void *handle)
- {
- /* Deal with Filer double-clicks on Planets files */
- spriteareaheader *sprite_area;
- _kernel_oserror *err;
-
- /* convert to sprites */
- if(planets_to_sprites((SF_PlanetsSetHdr **)buffer, &sprite_area)) {
-
- /* save spritefile to !Scrap */
- nobudge_register(256);
- err = _swix(OS_SpriteOp, _INR(0,2), SPRITEOP_SAVE_AREA+SPRITEOP_USERAREA_SPRNAME, sprite_area, "<Wimp$Scrap>");
- nobudge_deregister();
- if(err != NULL)
- err_report(err->errnum, msgs_lookup_sub1("SaveFail", err->errmess));
- else {
- /* open spritefile (in Paint?) */
- if(_kernel_oscli("Filer_Run <Wimp$Scrap>") == _kernel_ERROR)
- err_check_rep(_kernel_last_oserror());
- }
- flex_free((flex_ptr)&sprite_area);
- }
- flex_free(buffer);
- }
-